/*
 * Copyright (C) 2021-2023, WeiStudio
 *
 * License: Apache-2.0
 *
 * Change Logs:
 * Date			Author		    Note
 * 2021-07-20	WeiStudio		the first version
 * 2022-10-25   WeiStudio       add bitmap
 */



#include "qe_service.h"
#include "qe_platform.h"
#include <stdarg.h>



 /* global errno */
static volatile int qe_errno;

qe_err_t qe_get_errno(void)
{
	 return qe_errno;
}

void qe_set_errno(qe_err_t e)
{
	 qe_errno = e;
}
 
int *_qe_errno(void)
{
    return (int *)&qe_errno;
}

int qe_cpu_endian(void)
{
	union {
		unsigned long int i;
		unsigned char s[4];
	}c;

	c.i = 0x12345678;
	return (0x12 == c.s[0]);
}

#define qe_biglittle_swap16(a)	((((qe_u16)(a) & 0xff00) >> 8) | (((qe_u16)(a) & 0x00ff) << 8))

#define qe_biglittle_swap32(a) 	((((qe_u32)(a) & 0xff000000) >> 24) | \
								  (((qe_u32)(a) & 0x00ff0000) >> 8) | \
								  (((qe_u32)(a) & 0x0000ff00) << 8) | \
								  (((qe_u32)(a) & 0x000000ff) << 24))

unsigned long int qe_htonl(unsigned long int x)
{
	return qe_cpu_endian() ? x : qe_biglittle_swap32(x);
}

unsigned short int qe_htons(unsigned short int x)
{
	return qe_cpu_endian() ? x : qe_biglittle_swap16(x);
}


void (*qe_assert_hook)(const char *ex, const char *func, qe_size_t line);

/**
 * This function will set a hook to assert.
 *
 * @hook: the hook function
 */
void qe_assert_set_hook(void (*hook)(const char *, const char *, qe_size_t))
{
	qe_assert_hook = hook;
}

void qe_assert_handler(const char *ex_string, const char *func, qe_size_t line)
{
	volatile char dummy = 0;
	
	if (qe_assert_hook == QE_NULL) {
		while (dummy == 0);
	} else {
		qe_assert_hook(ex_string, func, line);
	}
}

inline int qe_strb_build(qe_strb_t *strb, const char *fmt, ...)
{
	int len;
	va_list ap;
	
	va_start(ap, fmt);
	len = qe_vsnprintf(strb->p, strb->max, fmt, ap);
	va_end(ap);

	strb->max -= len;
	strb->len += len;
	strb->p += len;
	
	return len;
}

inline qe_strb_t qe_strb_frombuf(char *buf, int size)
{
	qe_strb_t strb;

	strb.head = buf;
	strb.len  = 0;
	strb.max  = size;
	strb.p    = buf;
	return strb;
}

inline qe_strb_t qe_strb_make(char *s, int max)
{
	qe_strb_t strb;

	strb.p = s;
	strb.head = s;
	strb.max = max;
	strb.len = qe_strlen(s);
	return strb;
}